################################################################################
### Geographical Representation on the Floor:
### Parliamentary Rules and Legislative Speeches in Party‐Centered Contexts
### Author: Edoardo Alberto Viganò

### Manuscript
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

# List of required packages
required_pkgs <- c(
  "here", "dplyr", "tidyr", "stringr",
  "survival", "fixest", "stargazer",
  "marginaleffects", "ggplot2", "vtable"
)

# Install any that are missing
to_install <- required_pkgs[!(required_pkgs %in% installed.packages()[,"Package"])]
if(length(to_install)) install.packages(to_install, dependencies = TRUE)

# Load all
invisible(lapply(required_pkgs, library, character.only = TRUE))

### Load data
speeches <- readRDS(here("speeches_desc.rds"))
speeches_MP_17 <- readRDS(here("speeches_MP_17_desc.rds"))
speeches_MP_18 <- readRDS(here("speeches_MP_18_desc.rds"))
speeches_pt <- readRDS(here("speeches_main.rds"))
speeches_sw <- readRDS(here("speeches_sw.rds"))


### TABLE 1
# % of regional speeches
summary_17 <- speeches %>% filter(term == "17")
summary_18 <- speeches %>% filter(term == "18")

st(summary_17,
   group = 'conversion',
   vars = c('reg_sp'),
   out = 'viewer', 
   group.test = TRUE,
   digits = 2)

st(summary_18,
   group = 'conversion',
   vars = c('reg_sp'),
   out = 'viewer',
   group.test = TRUE,
   digits = 2)

st(speeches,
   group = 'conversion',
   vars = c('reg_sp'),
   out = 'viewer',
   group.test = TRUE,
   digits = 2)

# Number of speeches per MP
# term 2013–2018
summ_17 <- speeches_MP_17 %>%
  summarise(
    N_party  = sum(!is.na(count_sb)),
    Mean_party = mean(count_sb, na.rm = TRUE),
    SD_party   = sd(count_sb, na.rm = TRUE),
    N_open  = sum(!is.na(count_sc)),
    Mean_open = mean(count_sc, na.rm = TRUE),
    SD_open   = sd(count_sc, na.rm = TRUE)
  ) %>%
  mutate(Term = "2013-2018")

# term 2018–2022
summ_18 <- speeches_MP_18 %>%
  summarise(
    N_party  = sum(!is.na(count_sb)),
    Mean_party = mean(count_sb, na.rm = TRUE),
    SD_party   = sd(count_sb, na.rm = TRUE),
    N_open  = sum(!is.na(count_sc)),
    Mean_open = mean(count_sc, na.rm = TRUE),
    SD_open   = sd(count_sc, na.rm = TRUE)
  ) %>%
  mutate(Term = "2018-2022")

# both terms combined
summ_both <- bind_rows(speeches_MP_17, speeches_MP_18) %>%
  summarise(
    N_party  = sum(!is.na(count_sb)),
    Mean_party = mean(count_sb, na.rm = TRUE),
    SD_party   = sd(count_sb, na.rm = TRUE),
    N_open  = sum(!is.na(count_sc)),
    Mean_open = mean(count_sc, na.rm = TRUE),
    SD_open   = sd(count_sc, na.rm = TRUE)
  ) %>%
  mutate(Term = "Both")

num_speeches <- bind_rows(summ_17, summ_18, summ_both)

num_speeches

### TABLE 2
glm1_1 <- clogit(reg_sp ~ conversion + strata(deputato), speeches_pt)

glm1_2 <- clogit(reg_sp ~ conversion + nwords + rapporteur + gov_party + as.factor(year) +
                   as.factor(cap)  + strata(deputato), speeches_pt)

stargazer(glm1_1, glm1_2, 
          omit = c("cap", "year"), 
          title = "Floor rules and geographical speeches, conditional logistic regression", 
          dep.var.labels = "Geographical speech",
          type = "text",
          style = "ajps", single.row = F,
          covariate.labels = c("Open-access", "Speech length", "Rapporteur", "Government party"))


### FIGURE 1
# Panel (a)
glm2_2 <- glm(
  reg_sp ~ conversion*loyalty + nwords + rapporteur +
    gov_office + office + gov_party + local + south +
    male + age + factor(leg_term) + factor(cap),
  family = binomial(link = "logit"),
  data = speeches_sw
)

plot_comparisons(glm2_2, variables = "conversion", condition = "loyalty", 
                 conf_level = 0.95, rug = T) + 
  xlim(0.92, 1) +
  ylim(0, 0.11) + 
  geom_hline(yintercept = 0, linetype="dotted", size = 0.5) +
  xlab("Loyalty") + ylab("Marginal effect of open rules") +
  theme_classic()


# Panel (b)
glm3_2 <- feglm(reg_sp ~ conversion*as.factor(distr_topic) + nwords + 
                  rapporteur  + as.factor(year) | deputato, 
                speeches, cluster = "deputato")

# Due to incompatibilty of feglm with updated marginaleffects, install older version
packageurl <- "https://cran.r-project.org/src/contrib/Archive/marginaleffects/marginaleffects_0.25.1.tar.gz"
install.packages(packageurl, repos=NULL, type="source")
library(marginaleffects)

plot_comparisons(glm3_2, variables = "conversion", condition = "distr_topic", # localadm  backbencher
                 conf_level = 0.95) +
  xlab("District topic") + ylab("Marginal effect of open rules") +
  scale_x_discrete(breaks = c("0","1"),
                   labels = c("No", "Yes")) +
  theme_classic()


# Panel (c)
glm4_2 <- feglm(reg_sp ~ conversion*maj_tier + nwords + rapporteur +
                  gov_office + office + gov_party + local + south + maj_tier +
                  + male + age  + as.factor(leg_term) + as.factor(cap), 
                family = binomial(link = "logit"),    
                data = speeches_sw)

plot_comparisons(glm4_2, variables = "conversion", condition = "maj_tier", 
                 conf_level = 0.95) + 
  xlab("Majoritarian tier") + ylab("Marginal effect of open rules") +
  scale_x_discrete(breaks = c("0","1"),
                   labels = c("No", "Yes")) +
  theme_classic()



